if (!QSAPI) {
	var QSAPI = {
		Widget : {}
	};
} else if (!QSAPI.Widget) {
	QSAPI.Widget = {};
}

QSAPI.Widget.RTQ_Options = function() {
	var t = QS_Lang.options;
	this.containerId = null;
	this.container = null;
	this.id = null;
	this.callback = {};
	this.profile = {
		fixHeight : true,
		hideExchange:true,
		selectedStrategy:1,
		selectedType:1,
		callback:{}
	};
	this.el = null;
	this.mainTicker = ''; // performance Id
	this.lastOption = null;
	this.size = {
		width : 800,
		height : 400
	};
	this.optionsTickerList=[];
	this.callList = [];
	this.putList = [];
	this.strikeList = [];
	this.scribeParaList = [];
	this.splitLineIndex = [];
	this.selectedTabIndex = -1;
	this.lastPrice = -1; // the last price for the main ticker, it is used to compair the strike price.
	this.hasOptionData = false;// 
	this.minWidth = 800;
	this.selectedType = 1; // show all;
	this.selectedRange = 1; // show in and out of money ticker.
	this.selectedExpr = 0;
	this.selectedExprText='';
	this.selectedNumOfCols = 6;
	this.dataCom=null;
	this.rangeFromProfile=false;
	this._contains = {
		gLeft : null,
		gMiddle : null,
		gRight : null,
		hLeft : null,
		hMiddle : null,
		hRight : null,
		msg : null
	}
	this.uiConfig = {
		settingPanel : null
	}
	this.exchDataList = [ {
		txt : t.composite,
		val : ""
	} ];
	this.typeDataList = [
	 {
	    txt: t.callsAndPuts,
	    val: 1
	 },{
		txt : t.calls,
		val : 2
	}, {
		txt : t.puts,
		val : 3
	} ];
	this.rangeDataList = [ {
		txt : t.all,
		val : 1
	}, {
		txt : t.inmoney,
		val : 2
	}, {
		txt : t.outmoney,
		val : 3
	}, {
		txt : t.atmoney,
		val : 4
	} ];
	this.viewDataList = [ {
		txt : t.lastprice,
		val : "LastPrice",
		haschecked : true
	}, {
		txt : t.daychange,
		val : "Chg",
		haschecked : true
	}, {
		txt : t.bidprice,
		val : "BidPrice",
		haschecked : true
	}, {
		txt : t.askprice,
		val : "AskPrice",
		haschecked : true
	}, {
		txt : t.volume,
		val : "Volume",
		haschecked : true
	}, {
		txt : t.openint,
		val : "OpenInt",
		haschecked : true
	} ]
	this.uiComponents = {
		callGrid : null,
		strikeGrid : null,
		putGrid : null,
		exprDDL : null,//expiration
		exchDDL : null,//exchange
		typeDDL : null,//type
		rangeDDL : null,//strategy
		viewGroup : null
	}
	this.callColumns = [];
	this.strikeColumns = [ {
		header : "StrikeId",
		align : "center",
		dataIndex : 'strikeId',
		width : '0',
		hide : true
	}, {
		header : t.strike,
		align : "center",
		dataIndex : 'strikePrice',
		width : '100%'
	} ];
	this.putColumns = [];
	this.loaded = false;
};

QSAPI.Widget.RTQ_Options.prototype = {
	t :QS_Lang.options,	
	init : function(profile,tickerObj, uiConfig) {
		if (profile) {
			$.extend(this.profile, profile);
		}
		$.extend(this.uiConfig, uiConfig);
		if (profile && profile.cols) {
			for ( var i = 0; i < this.viewDataList.length; i++) {
				if (profile.cols[this.viewDataList[i].val] == 0) {
					this.viewDataList[i].haschecked = false;
					this.selectedNumOfCols--;
				}
			}
		}
		this.size.width = profile.width || this.size.width, this.size.height = profile.height || this.size.height;
		this._createUI();
		this.selectedRange=this.profile.selectedStrategy;
		this.selectedType=this.profile.selectedType;
		this.__resetRangeFromProfile();
	},
	__resetRangeFromProfile:function(){
		if (this.selectedRange>1 || this.selectedType>1){
			this.rangeFromProfile=true;
		}
		
	},
	__subscribe:function(){
		var self=this;
		var grid=null;
		var symbols=[];
		if (self.uiComponents.callGrid){
			grid=self.uiComponents.callGrid;
			symbols=symbols.concat(self.__getSymbols(grid));
		}
		if (self.uiComponents.putGrid){
			grid=self.uiComponents.putGrid;
			symbols=symbols.concat(self.__getSymbols(grid));
		}
		self.__subscribeTickerObject(symbols);
	},
	__unSubscribe:function(){
		var self=this;
		if (self.optionsTickerList.length>0){
			var unSubscribeCallballs={
	    			onSuccess:function(){;},
	    			onFailure:function(){;}
			};
			var dm=QSAPI.DataManager;
		    if (dm._getType() == dm.TYPE.PUSH) {
		    	dm.unSubscribePush(self.dataCom, self.optionsTickerList,unSubscribeCallballs);
			} else if (dm._getType() == dm.TYPE.PULL) {
				dm.unSubscribePull(self.dataCom, self.optionsTickerList,unSubscribeCallballs);
			}			
		}
	},	
	__subscribeTickerObject:function(symbols){
		var dm=QSAPI.DataManager;
		var self=this;
		var subscribeCallballs={
    			onSuccess:function(){
    				//Log('Options subscribe');
    			},
    			onFailure:function(){;}
		};		
		QSAPI.TickerFactory.create(symbols, {
			onSuccess : function(tickerList) {
				self.optionsTickerList=tickerList;
				var len=tickerList.length;
				var cnt=0;
				self._bindSymbolToGrid(tickerList);
				self.dataCom = {
						subscribeID : 'qs_options_ticker_data_' + (self.id?self.id:Util.IdProducer.getId()),
						updateData : function(tickerObject, data) {							
							cnt++;
							self.updateData(tickerObject.gkey, data);
							if (cnt==len && self.rangeFromProfile){
									self.uiComponents.typeDDL.selectItemByValue(self.selectedType);								
									self.uiComponents.rangeDDL.selectItemByValue(self.selectedRange);
									self.changeType(self.selectedType);									
									self.rangeFromProfile=false;
							}
						}
					};				
				
			    if (dm._getType() == dm.TYPE.PUSH) {
			    	dm.subscribePush(self.dataCom, tickerList,subscribeCallballs);
				} else if (dm._getType() == dm.TYPE.PULL) {
					dm.subscribePull(self.dataCom, tickerList,subscribeCallballs);
				}
			}
		});
	},
	_bindSymbolToGrid:function(tickerList){
		var pg = this.uiComponents.putGrid, cg = this.uiComponents.callGrid;
		var grid;
		for(var i=0;i<tickerList.length;i++){
			if(tickerList[i].optiontype=="C"){
				grid = cg
			}else if(tickerList[i].optiontype=="P"){
				grid = pg;
			}
			if(!grid.DOMMap[tickerList[i].gkey]||!grid.DOMMap[tickerList[i].gkey]["clientTicker"]) continue;
			grid.DOMMap[tickerList[i].gkey]["clientTicker"].innerHTML = tickerList[i].clientTicker;
		}
	},
	pause:function(){
		this.__unSubscribe();
	},
	__getSymbols:function(grid){
		var result=[];
		for(var key in grid.rows){
			var tmp=key.split(":");
			//result.push(grid.rows[key].data.tcode+'.2.'+tmp[1]);
			result.push(tmp[1]);
		}
		return result;
	},	
	addOptions:function(tickerObj,callback){
		if (tickerObj.valid){
			var gkey=this.gkey=tickerObj.getField("gkey");
			var mainTicker=this.mainTicker =(tickerObj.getField('exch') || "") + (tickerObj.getField('exch') ? ":" : "") + (tickerObj.ticker || "");
            var self = this;
            var url = "//qt.morningstar.com/switchservice/getoptionchain.ashx?t=" + mainTicker + "&region=" + tickerObj.country + "&cb=?";
            $.getJSON(url,function(d){
            	if (typeof(callback.onBindData)=='function'){
            		$.extend(true,self.profile.callback,callback);
            	}
                self.optionsArrived(d);
                self.selectedExprText=self.uiComponents.exprDDL._getTxtByValue(self.selectedTabIndex);
                self.bindGridData(self.selectedTabIndex);  
                self.__subscribe();
            });
		}else{
			
		}
	},
	
    optionsArrived:function(data){  // when option chain arrive at browse.
        this.splitLineIndex = [];
        if(data&&data.Chain){
			this._contains.msg.hide();
			this.hasOptionData = true;
			var info = data.Chain;
			var dateList = info.Expirations;
			var detailList = info.Details;
			var tabData=[],expireD=[],tIndex = 0;
			for(var i=0;i<dateList.length;i++){
				if(this._convertToDate(dateList[i]).getTime()+24*60*60*1000<=new Date().getTime()){
					expireD.push(i);
					continue;
				}
				tabData.push({txt:this._formateDate(dateList[i]),val:tIndex});
				tIndex++;
			}
			this.uiComponents.exprDDL.rebindData(tabData);
			this.uiComponents.exprDDL.selectItemByValue(tabData[0]['val']);
			this.callList = [],this.putList = [],this.strikeList=[],this.scribeParaList=[];
			var tcode="";
			var dlIndex = 0;
			for(var i=0;i<detailList.length;i++){
				if($.inArray(dlIndex,expireD)>-1){
					detailList.splice(i,1);
					i--;
					dlIndex++;
					continue;
				}
				dlIndex++;
				this.callList[i]=[],this.putList[i]=[],this.strikeList[i]=[],this.scribeParaList[i]={"C":[],"P":[]};
				var strikeMap={},pIndex=0,cIndex=0,sId=1,cId=1,pId=1;
				this.strikeList[i]=[];
				for(var j=0;j<detailList[i].length;j++){
					var t = detailList[i][j].Info, feed = detailList[i][j].Feed;
					tcode = feed[1]=="3"?"126":feed[1];
					if(t[3]== "C"){
						this.callList[i][cIndex]={tcode:feed[1],gkey:tcode + ":" + feed[0],symbol:t[0],strikePrice:t[4],strikeId:cId++};
						cIndex++;
					}else if(t[3]=="P"){
						this.putList[i][pIndex]={tcode:feed[1],gkey:tcode + ":" + feed[0],symbol:t[0],strikePrice:t[4],strikeId:pId++};
						pIndex++;
					}
					
					if(typeof(strikeMap[t[4]])=="undefined"){ // the first strik price.
					    strikeMap[t[4]]= t[3];
						this.strikeList[i].push({strikePrice:t[4],strikeId:sId++});
					}else{
						if(strikeMap[t[4]] != t[3]){  // same strik price and not type(call or put).
							delete strikeMap[t[4]];
						}
					}
				}
				this.strikeList[i].sort(function(a,b){
	                return parseFloat(a.strikePrice)>parseFloat(b.strikePrice)?1:-1
	            });
	            this.callList[i].sort(function(a,b){
	                return parseFloat(a.strikePrice)>parseFloat(b.strikePrice)?1:-1
	            });
	            this.putList[i].sort(function(a,b){
	                return parseFloat(a.strikePrice)>parseFloat(b.strikePrice)?1:-1
	            });
			}
			// sort the list.
		    this.selectedTabIndex = 0;
			this._setDDLAble();
		}else{  // no option tickers clear data.
			this.hasOptionData = false;
			this.callList = [],this.putList = [],this.strikeList=[],this.scribeParaList=[],this.selectedTabIndex=-1;
			this.uiComponents.exprDDL.rebindData([]);
			this.uiComponents.callGrid.empty();
            this.uiComponents.putGrid.empty();
            this.uiComponents.strikeGrid.empty();
			this._contains.msg.show();
		}
    },
    _updateLastPrice:function(lastPrice){
		this.lastPrice = lastPrice;
		if (this.lastPrice!=-1){
			this._initInTheMoneyBg(this.selectedTabIndex);
		}
    }, 
    _createUI:function(){
		var self = this,uiComps = this.uiComponents;
		this.el = $('<div class="rtq-options"><div class="bd"><div class="qs-option-toolbar">'+
				  '<div class="range"><h3>Strategy</h3></div><div class="type"><h3>Type</h3></div><div class="expr"><h3>Expiration</h3></div><div class="exchange"><h3>Exchange</h3></div>'+
                  '</div><div class="grid-header"><div class="wrap"><div class="h-left rtq-grid rtq-grid-auto" style="float:left;border:0"></div>'+
                  '<div class="h-mid rtq-grid rtq-grid-auto" style="float:left;border:0">'+
                  '</div><div class="h-right rtq-grid rtq-grid-auto" style="float:left;border:0"></div>'+
                  '</div></div><div class="grid-container"><div class="wrap clearfix"></div></div><div class="error-msg">No option available.</div></div></div>').appendTo(this.container);
		this._contains.msg = this.el.find(".error-msg").hide();	  
        //Strategy DDL
		uiComps.rangeDDL = new Util.DropDownList(this.el.find('.range')[0], function(t, v){
			if(self.selectedRange != v){
				var oldVal=self.selectedRange;
				self.selectedRange  = v;
				self.changeRange(v);
				self.parent.__executeCallback('onStateChange',{DropdownList:'Strategy',from:parseInt(oldVal),to:parseInt(v)});
			}
            
        }, this.rangeDataList, this._getDropDownListConfig(110));
		//Type DDL
		uiComps.typeDDL = new Util.DropDownList(this.el.find('.type')[0], function(t, v){
			if(self.selectedType != v){
				var oldVal=self.selectedType;
				self.selectedType = v;
                self.changeType(v);
                self.parent.__executeCallback('onStateChange',{DropdownList:'Type',from:parseInt(oldVal),to:parseInt(v)});                
			}
        }, this.typeDataList, this._getDropDownListConfig(110));
        //Expiration DDL
		uiComps.exprDDL = new Util.DropDownList(this.el.find('.expr')[0], function(t, v){
			if(self.selectedExpr != v){
				var oldText=self.selectedExprText;
				self.selectedExpr  = v;
				self.selectedExprText= t;
				if(v == self.selectedTabIndex ){return;}
				self.bindGridData(v);
				self.__resetRangeFromProfile();
				self.__unSubscribe();
				self.__subscribe();				
				self.selectedTabIndex = v;
				self.mapGridData();  // get data from "gdata".
				self.parent.__executeCallback('onStateChange',{DropdownList:'Expiration',from:oldText,to:t});				
			}
        }, [], this._getDropDownListConfig(100));	
		//Exchange DDL
		uiComps.exchDDL = new Util.DropDownList(this.el.find('.exchange')[0], function(){
        }, this.exchDataList, this._getDropDownListConfig(80)); 
		if (this.profile.hideExchange){
			this.el.find(".exchange").hide();
		}
		this.el.find(".grid-container .wrap").html('<div class="g-left"></div><div class="g-mid"></div><div class="g-right"></div>');
		var ww = this.size.width;
		if(this.size.width < this.minWidth) ww = this.minWidth;
        this.headerContainer = this.el.find(".grid-header").css({width:ww});
        this.gridContainer = this.el.find(".grid-container").css({width:ww});
		this._setMinWidth(true);
		var w = 0.5*(ww-60);
		this._contains.gLeft= this.el.find(".g-left").css({width:w});
		this._contains.gMiddle= this.el.find(".g-mid").css({width:"60px"});
		this._contains.gRight= this.el.find(".g-right").css({width:w});
		this._contains.hLeft= this.el.find(".h-left").css({width:w});
        this._contains.hMiddle= this.el.find(".h-mid").css({width:"60px"});
        this._contains.hRight= this.el.find(".h-right").css({width:w});
        this._creatGrids();
        this._createSettingPn();
		if (this.profile.fixHeight) {
			this.dataScrollPN = new Util.ScrollPanel(this.gridContainer[0], {}, {
				onScroll: function(sl, st){//mboheader
					  if (typeof(self.headerContainer) != "undefined") {
						  self.headerContainer.scrollLeft(sl);
					  }
				}
			});
        }
    },
	_changeCols:function(){
		this._createGridCols();
		this.uiComponents.callGrid.setColumnCfg(this.callColumns);
		this.uiComponents.putGrid.setColumnCfg(this.putColumns);
	},    
    _getDropDownListConfig:function(w){
        return {riggerByClick: false,
            width: w,
            disable: true,
            actionAtInit: false
        }
    },
	_setMinWidth:function(needCalculteMinWidth){
		if(needCalculteMinWidth){
			var w = 800;
			if(this.selectedType==2 || this.selectedType == 3){
				w = 430;
			}
			this.minWidth = w*0.25+0.75*w*this.selectedNumOfCols/6;
		}
		this.headerContainer.find(".wrap").css({"min-Width":this.minWidth+"px"});
		this.gridContainer.find(".wrap").css({"min-Width":this.minWidth+"px"});
	},
    _creatGrids:function(){
    	var self=this;
		this._createGridCols();
		this._contains.hLeft.html(""),this._contains.hMiddle.html(""),this._contains.hRight.html("");
		this._contains.gLeft.html(""),this._contains.gMiddle.html(""),this._contains.gRight.html("");
        this.uiComponents.callGrid = new Util.DataGrid(this._contains.gLeft, {}, this._getGridConfig(this.callColumns,400,"gkey",this._contains.hLeft,true),{onCellClick:function(e,cell,row){self._cellClick(e,cell,row,'Calls')}});
        this.uiComponents.strikeGrid = new Util.DataGrid(this._contains.gMiddle, {}, this._getGridConfig(this.strikeColumns,400,"strikeId",this._contains.hMiddle,false),{});
        this.uiComponents.putGrid = new Util.DataGrid(this._contains.gRight, {}, this._getGridConfig(this.putColumns,400,"gkey",this._contains.hRight,true),{onCellClick:function(e,cell,row){self._cellClick(e,cell,row,'Puts')}});
    },
    _cellClick:function(e,cell,row,type){
    	var rowdata={};
    	var s='<div></div>'
    	rowdata['Type']=type;
    	rowdata['Symbol']=$(row.DOMMap['symbol'].outerHTML).text();
    	rowdata['Last']=$(row.DOMMap['LastPrice']?row.DOMMap['LastPrice'].outerHTML:s).text();
    	rowdata['Chg']=$(row.DOMMap['Chg']?row.DOMMap['Chg'].outerHTML:s).text();
    	rowdata['Bid']=$(row.DOMMap['BidPrice']?row.DOMMap['BidPrice'].outerHTML:s).text();
    	rowdata['Ask']=$(row.DOMMap['AskPrice']?row.DOMMap['AskPrice'].outerHTML:s).text();
    	rowdata['Vol']=$(row.DOMMap['Volume']?row.DOMMap['Volume'].outerHTML:s).text();
    	rowdata['OpenInt']=$(row.DOMMap['OpenInt']?row.DOMMap['OpenInt'].outerHTML:s).text();
    	rowdata['Strike']=row['data']['strikePrice'];
    	if (typeof(this.callback.onClick)=='function'){
    		this.callback.onClick(rowdata);
    	}
    },
	_createGridCols:function(){
		this.putColumns = [], this.callColumns = [];
		var symbolColW = 27+73*0.4*(6-this.selectedNumOfCols)/6;
		var w = this.selectedNumOfCols >0?((99-symbolColW)/this.selectedNumOfCols).toFixed(2):56;
		this.putColumns.push({
                    align:"center",
                    header: "Puts",
                    dataIndex: 'clientTicker',
                    width: symbolColW+'%'
        });
		this.callColumns.push({
                    align:"center",
                    header: "Calls",
                    dataIndex: 'clientTicker',
                    width: symbolColW+'%'
        });
		for(var i=0;i<this.viewDataList.length;i++){
			if(this.viewDataList[i].haschecked){
				var item = {
                    align:"center",
                    header: this.viewDataList[i].txt,
                    dataIndex: this.viewDataList[i].val,
                    width: w+'%'
                }
				if(this.viewDataList[i].val=="Chg")item.className = "bold-cell";
				this.putColumns.push(item);
				this.callColumns.push(item)
			}
		}
		var eItem =[ {
                    header: this.t.strike,
                    align:"center",
                    dataIndex: 'strikePrice',
                    width: '0',
                    hide:true
            },{
                header: this.t.strike,
                align:"center",
                dataIndex: 'strikeId',
                width: '0',
                hide:true
        }]
		this.putColumns.push(eItem[0]),this.putColumns.push(eItem[1]);
        this.callColumns.concat(eItem[0]),this.callColumns.concat(eItem[1]);
	},_getGridConfig:function(columnData,defaultHeight,indexColKey,hContainer,resizeable){
        return {
            column: columnData,
            height: defaultHeight,
            htmlLayer: 'div',
            autoWidth: true,
            autoHeight: true,
            indexColKey: indexColKey,
            sortable: false,
            showYScrollbar: false,
			headerContainer:hContainer,
			cellResize:resizeable
        }
    },
	_convertToDate:function(odate){
		var t = odate.split("-");
        var dt = new Date(parseInt(t[0], 10), parseInt(t[1], 10) - 1, parseInt(t[2], 10));
		var dx = dt.getTime()-new Date().getTime();
		if(dx>30*3600*24*1000){ // monthly options change to Saturdays
			if(dt.getDay()==5){
				dt = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate()+1);
			}
		}else{   // weekly options
			if(dt.getDay()==6&&dt.getDate()<15&&dt.getDate()>22){ // make sure the day is friday.
				dt = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate()-1);
			}
		}
		return dt;
	},
	_formateDate: function(odate){ // YYYY-mm-DD
        var dt = this._convertToDate(odate);
        var dtFormat = QS_DateFmt.Mo[dt.getMonth()] + ' ' + dt.getDate() + ', ' + dt.getFullYear();
        return dtFormat;
    },
	_initInTheMoneyBg:function(index){
		if(this.hasOptionData&&this.lastPrice>0){ // has an vaild last price
		    var hasSplit = false;
            for(var i=0;i<this.strikeList[index].length;i++){
				var sPrice = this.strikeList[index][i]["strikePrice"];
                if(sPrice>this.lastPrice){
					if(i>=this.putList[index].length)continue;
                    this.uiComponents.putGrid.rows[this.putList[index][i].gkey].el.addClass("inmoney-row");
					if (!hasSplit) {
						hasSplit = true;
						this.splitLineIndex[index] = i;
					}
                }else if(sPrice<this.lastPrice){
					if(i>=this.callList[index].length)continue;
                    this.uiComponents.callGrid.rows[this.callList[index][i].gkey].el.addClass("inmoney-row");
                }
            }
        }
	},	
    _createSettingPn: function(){
        var self = this,uiComps = this.uiComponents, settingPn = $('.qs-ui-setpn');
        if(!settingPn) return;
        settingPn.html('<ul class="opt-settingpn" >' +         
            '<li class="subtitle">View</li><li class="view clearfix"></li></ul>');               
		uiComps.viewGroup = new Util.ButtonGroup(settingPn.find(".view"), this.viewDataList, {
			onClick: function(v,item){
				for (var i = 0; i < self.viewDataList.length; i++) {
					if(self.viewDataList[i].val == v){
						var oldstatus=self.viewDataList[i].haschecked;
						if(item.isSelected){
		                    self.viewDataList[i].haschecked = true;
							self.selectedNumOfCols++;
		                }else{
							self.viewDataList[i].haschecked = false;
							self.selectedNumOfCols--;
						}
						//self._createGridCols();
						self._changeCols();
						self._setMinWidth(true);
						self.bindGridData(self.selectedTabIndex);
						self.mapGridData();
						self.parent.__executeCallback('onStateChange',{Column:self.viewDataList[i].val,from:oldstatus,to:self.viewDataList[i].haschecked});				
						break;
					}					
				}
			}
		},{type:'checkbox',vertical:true});
		for(var i=0;i<this.viewDataList.length;i++){
			if(this.viewDataList[i].haschecked){
				uiComps.viewGroup.btns[this.viewDataList[i].val].select();
			}
		}
    },	
	mapGridData:function(){  // get data from "gData" to fill the grid cells.
		this._fillDataToGrid(this.uiComponents.callGrid,"C");
		this._fillDataToGrid(this.uiComponents.putGrid,"P");
	},
	updateData:function(gkey,fields){
			if (this.uiComponents.callGrid.DOMMap[gkey]){
				this._refreshData(this.uiComponents.callGrid, gkey,fields);
			}
			if (this.uiComponents.putGrid.DOMMap[gkey]){
				this._refreshData(this.uiComponents.putGrid, gkey,fields);
			}
	},
	_refreshData:function(grid,gkey,fields){
		var type, gValue,el,value;
		for(var o in fields){
			type = fields[o].dataType;
			gValue = gData[gkey][o];
			el = grid.DOMMap[gkey][o];
			if(!el) continue;
			if(type=="f"){				
				value = isNaN(gValue)?"--":Math.abs(gValue)>=0.01?gValue.toFixed(2):gValue;
			}else{
				value = gValue;
			}
			if(el){
				el.innerHTML = value;				
			}
			
			if (gValue!=fields[o].oldValue){
				if(o=="LastPrice"){ // falsh colorful background.
					Util.flash(el, gValue, fields[o].oldValue);
				}else if(o=="Chg"){// change color of font according the value.
					Util.flashWithDirectional(el, gValue, fields[o].oldValue,gValue>=0);
				}else if(o=="AskPrice"||o=="BidPrice"||o=="OpenInt"){// flash gray background
					Util.flash(el, null, null);				
				}
			}
		}		
	},
	_fillDataToGrid:function(grid,type){
		var el,value, op="all",isHide=false;
		if(this.selectedRange==2){ // in the money
			op= type=="C"?"<":">";
		}else if(this.selectedRange==3){ //out of money.
			op= type=="C"?">":"<";
		}else if(this.selectedRange==4){ // at the money
			op= "=";
		}
		isHide = ((type=="C"&&this.selectedType==2)||(type=="P"&&this.selectedType==3));
		for(var key in grid.rows){
            if(!gData[key]) continue;
			var da = grid.rows[key].data["strikePrice"],dId = grid.rows[key].data["strikeId"];
			if(op=="<"&&da>=this.lastPrice){ // 
				this.clearRowdata(grid.rows[key],dId,isHide);
			}else if(op==">"&&da<=this.lastPrice){
				this.clearRowdata(grid.rows[key],dId,isHide);
			}else if(op=="="&&da!=this.lastPrice){
				this.clearRowdata(grid.rows[key],dId,isHide);
			}else{
				for(var o in grid.rows[key].cells){
	                if(o=="Volume"||o=="OpenInt")value = isNaN(gData[key][o])?"":parseInt(gData[key][o],10).toFixed(0);
					else if (o=="clientTicker") value = gData[key][o];
	                else if(o=="strikePrice"){ //o=="clientTicker"||
	                    continue;
	                }else value = isNaN(gData[key][o])?"": parseFloat(gData[key][o]).toFixed(2);
	                grid.DOMMap[key][o].innerHTML = value;
	                if(o=="Chg"&&value!=""){
	                    Util.flashWithDirectional(grid.DOMMap[key][o], value, null,value>=0);
	                }
	            }
			}    
        }
	},
	changeRange:function(v){
		this.bindGridData(this.selectedTabIndex);
		this.mapGridData();	
	},	
	_setDDLAble:function(){
		if(this.uiComponents.exchDDL) this.uiComponents.exchDDL.setDisable(false);
		if(this.uiComponents.typeDDL) this.uiComponents.typeDDL.setDisable(false);
		if(this.uiComponents.rangeDDL) this.uiComponents.rangeDDL.setDisable(false);
		if(this.uiComponents.exprDDL) this.uiComponents.exprDDL.setDisable(false);
	},
	clearRowdata:function(row,strikeId,isHide){
		for(var o in row.cells){
			row.cells[o].innerDom.innerHTML = "";
		}
		if(isHide){
			row.el.hide();
			this.uiComponents.strikeGrid.rows[strikeId].el.hide();
		}else{
			row.el.show();
			this.uiComponents.strikeGrid.rows[strikeId].el.show();
		}
	},	
	bindGridData:function(index){
		if (index>=0){
			if(typeof(this.showLoading)=="function")this.showLoading(true);
	        this.uiComponents.callGrid.reBindData(this.callList[index]);
	        this.uiComponents.putGrid.reBindData(this.putList[index]);
	        this.uiComponents.strikeGrid.reBindData(this.strikeList[index]);
			this._initInTheMoneyBg(index);
	        this.changeOutSize(this.size.width,this.size.height);
			if (typeof (this.profile.callback.onBindData) =='function'){
				this.profile.callback.onBindData(index);
			}
		}
	},
	changeType:function(v){
		var con = this._contains, hCon=this.headerContainer.find(".wrap"),gCon = this.gridContainer.find(".wrap");
		if(v==1){ // show all
			con.gMiddle.insertAfter(con.gLeft);
            con.hMiddle.insertAfter(con.hLeft);
		    con.gLeft.show();
		    con.gRight.show();
			con.hLeft.show();
            con.hRight.show();	
		}else if(v==2){//only show call,		
			con.gLeft.show();
            con.gRight.hide();
			con.hLeft.show();
            con.hRight.hide();
			con.gMiddle.insertBefore(con.gLeft);
			con.hMiddle.insertBefore(con.hLeft);
		}else if(v==3){//only show put,		
		    con.gLeft.hide();
            con.gRight.show();
			con.hLeft.hide();
            con.hRight.show();
		}
		this._setMinWidth(true);
		if(this.selectedRange == 2 || this.selectedRange==3){
            this.mapGridData();
        }
		this.changeOutSize(this.size.width,this.size.height);
	},
	changeOutSize:function(width,height){
		var self=this;
		if (self.profile.fixHeight){
			var realW=width<self.minWidth?self.minWidth:width;//window's width
			var iw = (self.selectedType==1?0.5:1)*(realW-60);// the grid real width, there are two grids in options, selectType equals one means both two grids are shown, so, the width of each grid are half of the whole width
			var rw = self.selectedType==3||self.selectedType==1?self._contains.gRight.width():self._contains.gLeft.width();
			var aw = iw>rw?rw:iw;
			if(self.selectedType==2||self.selectedType==1){ //all or calls.
				self._contains.gLeft.css({width:aw-18}); 
				self._contains.hLeft.css({width:aw-18});
			}
			if(self.selectedType==1||self.selectedType==3){ // all or puts.
				self._contains.gRight.css({width:aw-18});  // reduce the width of grid to aviod the right grid wrap.
				self._contains.hRight.css({width:aw-18});
			}
			self.dataScrollPN.reSize(width, height-54);
			self.size.width = width;
			self.size.height = height;
			self.el.css({width:self.size.width});
			clearTimeout(self.optionWidgetTimer);
			self.optionWidgetTimer=setTimeout(function(){
				var dx = 60;
				if(!self.dataScrollPN.scrollbarX.isShow&&self.dataScrollPN.scrollbarY.isShow){
					dx = 76;
				}
				var ww = width;
				if(ww<self.minWidth){
					ww = self.minWidth;
				}
				var w = 0.5*(ww-dx), lw,rw;
				if(self.selectedType==2){// show call 
					lw = 2*w,rw=0;
				}else if(self.selectedType==3){
					rw = 2*w,lw=0;
				}else{
					lw = rw =w;
				}	
				self.headerContainer.css({width:width});
				self.gridContainer.css({width:width});
				self._contains.gLeft.css({width:lw});
				self._contains.gMiddle.css({width:"60px"});
				self._contains.gRight.css({width:rw});
				self._contains.hLeft.css({width:lw});
				self._contains.hMiddle.css({width:"60px"});
				self._contains.hRight.css({width:rw});
			},200)
	    }	
		else{
			this.onHeightChange(this.el.outerHeight(true));
		}
	},
    onHeightChange:function(height){
        if (!this.loaded) {
            this.loaded = true;
            this.lastCallbackHeight = height;
            if (typeof this.profile.callback.onLoad == 'function') {
                this.profile.callback.onLoad({
                    component: 'option',
                    height: height
                });
            }
        }else {
            if (this.lastCallbackHeight != height) {
                this.lastCallbackHeight = height;
                if (typeof this.profile.callback.onHeightChange == 'function') {
                    this.profile.callback.onHeightChange({
                        component: 'option',
                        height: this.lastCallbackHeight
                    });
                }
            }
        }
    },
    clear:function(){
        for(var p in this){
            if(!p || p == 'clear'){continue;}
            this[p] = null;
            delete this[p];
        }
    }
}